Added gtkpacker
authorCDT 1998 Shawn T. Amundson <amundson@gtk.org>
Fri, 12 Jun 1998 00:49:11 +0000 (00:49 +0000)
committerShawn Amundson <amundson@src.gnome.org>
Fri, 12 Jun 1998 00:49:11 +0000 (00:49 +0000)
Thu Jun 11 14:38:33 CDT 1998 Shawn T. Amundson <amundson@gtk.org>

        * gtk/gtkpacker.c, gtk/gtkpacker.h, gtk/gtk.h, gtk/Makefile.am:
          Added gtkpacker

        * examples/packer/pack.c, examples/packer/Makefile: Added
          gtkpacker example

14 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
Makefile.am
examples/packer/Makefile [new file with mode: 0644]
examples/packer/pack.c [new file with mode: 0644]
gtk/Makefile.am
gtk/gtk.h
gtk/gtkpacker.c [new file with mode: 0644]
gtk/gtkpacker.h [new file with mode: 0644]

index 0efb63f26eec1b0990eb042b0183d79229553a23..97e89da8b04cdb270a4fee60aed4098246c7e5d3 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Thu Jun 11 14:38:33 CDT 1998 Shawn T. Amundson <amundson@gtk.org>
+
+       * gtk/gtkpacker.c, gtk/gtkpacker.h, gtk/gtk.h, gtk/Makefile.am: 
+         Added gtkpacker
+
+       * examples/packer/pack.c, examples/packer/Makefile: Added
+         gtkpacker example
+
 Thu Jun 11 13:09:00 1998  Owen Taylor  <otaylor@gtk.org>
 
        * gtk/gtktext.c (remove_cache_line): Fixed broken
index 0efb63f26eec1b0990eb042b0183d79229553a23..97e89da8b04cdb270a4fee60aed4098246c7e5d3 100644 (file)
@@ -1,3 +1,11 @@
+Thu Jun 11 14:38:33 CDT 1998 Shawn T. Amundson <amundson@gtk.org>
+
+       * gtk/gtkpacker.c, gtk/gtkpacker.h, gtk/gtk.h, gtk/Makefile.am: 
+         Added gtkpacker
+
+       * examples/packer/pack.c, examples/packer/Makefile: Added
+         gtkpacker example
+
 Thu Jun 11 13:09:00 1998  Owen Taylor  <otaylor@gtk.org>
 
        * gtk/gtktext.c (remove_cache_line): Fixed broken
index 0efb63f26eec1b0990eb042b0183d79229553a23..97e89da8b04cdb270a4fee60aed4098246c7e5d3 100644 (file)
@@ -1,3 +1,11 @@
+Thu Jun 11 14:38:33 CDT 1998 Shawn T. Amundson <amundson@gtk.org>
+
+       * gtk/gtkpacker.c, gtk/gtkpacker.h, gtk/gtk.h, gtk/Makefile.am: 
+         Added gtkpacker
+
+       * examples/packer/pack.c, examples/packer/Makefile: Added
+         gtkpacker example
+
 Thu Jun 11 13:09:00 1998  Owen Taylor  <otaylor@gtk.org>
 
        * gtk/gtktext.c (remove_cache_line): Fixed broken
index 0efb63f26eec1b0990eb042b0183d79229553a23..97e89da8b04cdb270a4fee60aed4098246c7e5d3 100644 (file)
@@ -1,3 +1,11 @@
+Thu Jun 11 14:38:33 CDT 1998 Shawn T. Amundson <amundson@gtk.org>
+
+       * gtk/gtkpacker.c, gtk/gtkpacker.h, gtk/gtk.h, gtk/Makefile.am: 
+         Added gtkpacker
+
+       * examples/packer/pack.c, examples/packer/Makefile: Added
+         gtkpacker example
+
 Thu Jun 11 13:09:00 1998  Owen Taylor  <otaylor@gtk.org>
 
        * gtk/gtktext.c (remove_cache_line): Fixed broken
index 0efb63f26eec1b0990eb042b0183d79229553a23..97e89da8b04cdb270a4fee60aed4098246c7e5d3 100644 (file)
@@ -1,3 +1,11 @@
+Thu Jun 11 14:38:33 CDT 1998 Shawn T. Amundson <amundson@gtk.org>
+
+       * gtk/gtkpacker.c, gtk/gtkpacker.h, gtk/gtk.h, gtk/Makefile.am: 
+         Added gtkpacker
+
+       * examples/packer/pack.c, examples/packer/Makefile: Added
+         gtkpacker example
+
 Thu Jun 11 13:09:00 1998  Owen Taylor  <otaylor@gtk.org>
 
        * gtk/gtktext.c (remove_cache_line): Fixed broken
index 0efb63f26eec1b0990eb042b0183d79229553a23..97e89da8b04cdb270a4fee60aed4098246c7e5d3 100644 (file)
@@ -1,3 +1,11 @@
+Thu Jun 11 14:38:33 CDT 1998 Shawn T. Amundson <amundson@gtk.org>
+
+       * gtk/gtkpacker.c, gtk/gtkpacker.h, gtk/gtk.h, gtk/Makefile.am: 
+         Added gtkpacker
+
+       * examples/packer/pack.c, examples/packer/Makefile: Added
+         gtkpacker example
+
 Thu Jun 11 13:09:00 1998  Owen Taylor  <otaylor@gtk.org>
 
        * gtk/gtktext.c (remove_cache_line): Fixed broken
index 0efb63f26eec1b0990eb042b0183d79229553a23..97e89da8b04cdb270a4fee60aed4098246c7e5d3 100644 (file)
@@ -1,3 +1,11 @@
+Thu Jun 11 14:38:33 CDT 1998 Shawn T. Amundson <amundson@gtk.org>
+
+       * gtk/gtkpacker.c, gtk/gtkpacker.h, gtk/gtk.h, gtk/Makefile.am: 
+         Added gtkpacker
+
+       * examples/packer/pack.c, examples/packer/Makefile: Added
+         gtkpacker example
+
 Thu Jun 11 13:09:00 1998  Owen Taylor  <otaylor@gtk.org>
 
        * gtk/gtktext.c (remove_cache_line): Fixed broken
index 509221a6df4e78c1e71dcac6cef17f0e49072aa0..332e3b74f70472cd0b4693ac1ce9ca7468c8baae 100644 (file)
@@ -41,6 +41,8 @@ EXTRA_DIST =  \
        examples/menu/mfmain.h  \
        examples/notebook/Makefile  \
        examples/notebook/notebook.c  \
+       examples/packer/Makefile  \
+       examples/packer/pack.c \
        examples/packbox/Makefile  \
        examples/packbox/packbox.c  \
        examples/paned/Makefile  \
diff --git a/examples/packer/Makefile b/examples/packer/Makefile
new file mode 100644 (file)
index 0000000..27cbc80
--- /dev/null
@@ -0,0 +1,8 @@
+
+CC = gcc
+
+pack: pack.c
+       $(CC) `gtk-config --cflags` `gtk-config --libs` pack.c -o pack
+
+clean: 
+       rm -f pack
diff --git a/examples/packer/pack.c b/examples/packer/pack.c
new file mode 100644 (file)
index 0000000..2aafa11
--- /dev/null
@@ -0,0 +1,664 @@
+/* 
+ *  This is a demo of gtkpacker. 
+ */
+
+#include <gtk/gtk.h>
+
+void add_widget (GtkWidget *widget, gpointer data);
+void toggle_side (GtkWidget *widget, gpointer data);
+void toggle_anchor (GtkWidget *widget, gpointer data);
+void toggle_options (GtkWidget *widget, gpointer data);
+
+typedef struct {
+    GList     *widgets;
+    GtkWidget *packer;
+    GtkWidget *current;
+    GtkPackerChild *pchild;
+
+    GtkWidget *button_top;
+    GtkWidget *button_bottom;
+    GtkWidget *button_left;
+    GtkWidget *button_right;
+
+    GtkWidget *button_n;
+    GtkWidget *button_ne;
+    GtkWidget *button_nw;
+    GtkWidget *button_e;
+    GtkWidget *button_w;
+    GtkWidget *button_s;
+    GtkWidget *button_se;
+    GtkWidget *button_sw;
+    GtkWidget *button_center;
+
+    GtkWidget *button_fillx;
+    GtkWidget *button_filly;
+    GtkWidget *button_expand;
+} Info;
+
+void destroy (GtkWidget *widget, gpointer data)
+{
+    gtk_main_quit ();
+}
+
+int
+main (int argv, char **argc)
+{
+    GtkWidget *window;
+    GtkWidget *window_pack;
+    GtkWidget *top_pack;
+    GtkWidget *frame;
+    GtkWidget *packer;
+    GtkWidget *button_pack;
+    GtkWidget *button_add;
+    GtkWidget *button_quit;
+    GtkWidget *bottom_pack;
+    GtkWidget *side_frame;
+    GtkWidget *side_pack;
+    GtkWidget *button_top;
+    GtkWidget *button_bottom;
+    GtkWidget *button_left;
+    GtkWidget *button_right;
+    GtkWidget *anchor_table;
+    GtkWidget *anchor_frame;
+    GtkWidget *button_n;
+    GtkWidget *button_ne;
+    GtkWidget *button_nw;
+    GtkWidget *button_e;
+    GtkWidget *button_w;
+    GtkWidget *button_center;
+    GtkWidget *button_s;
+    GtkWidget *button_se;
+    GtkWidget *button_sw;
+    GtkWidget *button_expand;
+    GtkWidget *button_fillx;
+    GtkWidget *button_filly;
+    GtkWidget *options_pack;
+    GtkWidget *options_frame;
+    GtkWidget *anchor_pack;
+    Info *info;
+
+    gtk_init(&argv, &argc);
+
+    info = g_malloc(sizeof(Info));
+
+    window = gtk_window_new(GTK_TOPLEVEL);
+    gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                        GTK_SIGNAL_FUNC (destroy), NULL);
+
+    window_pack = gtk_packer_new();
+    gtk_container_add(GTK_CONTAINER(window), window_pack);
+    gtk_container_border_width(GTK_CONTAINER(window), 4);
+
+    top_pack = gtk_packer_new();
+    gtk_packer_add_defaults(GTK_PACKER(window_pack),
+                            top_pack,
+                            GTK_SIDE_TOP,
+                            GTK_ANCHOR_CENTER,
+                            GTK_FILL_X | GTK_FILL_Y | GTK_EXPAND);
+
+    frame = gtk_frame_new("Packing Area");
+    gtk_widget_set_usize(frame, 400, 400);
+    gtk_packer_add(GTK_PACKER(top_pack), 
+                             frame,
+                             GTK_SIDE_LEFT,
+                             GTK_ANCHOR_CENTER,
+                             GTK_FILL_X | GTK_FILL_Y | GTK_EXPAND,     
+                             0, 8, 8, 0, 0);
+    packer = gtk_packer_new();
+    gtk_container_add(GTK_CONTAINER(frame), packer);
+
+    button_pack = gtk_packer_new();
+    gtk_packer_add(GTK_PACKER(top_pack),
+                   button_pack, 
+                   GTK_SIDE_LEFT,
+                   GTK_ANCHOR_N,
+                   0, 
+                   0, 0, 0, 0, 0);
+
+    button_add = gtk_button_new_with_label("Add Button");
+    gtk_packer_add(GTK_PACKER(top_pack),
+                   button_add, 
+                   GTK_SIDE_TOP,
+                   GTK_ANCHOR_CENTER,
+                   GTK_FILL_X, 
+                   0, 8, 8, 8, 0);
+    gtk_signal_connect (GTK_OBJECT (button_add), "clicked",
+                        GTK_SIGNAL_FUNC (add_widget), (gpointer) info);
+
+    button_quit = gtk_button_new_with_label("Quit");
+    gtk_packer_add(GTK_PACKER(top_pack),
+                   button_quit, 
+                   GTK_SIDE_TOP,
+                   GTK_ANCHOR_CENTER,
+                   GTK_FILL_X, 
+                   0, 8, 8, 0, 0);
+    gtk_signal_connect_object (GTK_OBJECT (button_quit), "clicked",
+                               GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                               GTK_OBJECT (window));
+
+    bottom_pack = gtk_packer_new();
+    gtk_packer_add_defaults(GTK_PACKER(window_pack),
+                            bottom_pack,
+                            GTK_SIDE_TOP,
+                            GTK_ANCHOR_CENTER,
+                            GTK_FILL_X);
+  
+    side_frame = gtk_frame_new("Side");
+    gtk_packer_add(GTK_PACKER(window_pack),
+                   side_frame,
+                   GTK_SIDE_LEFT,
+                   GTK_ANCHOR_W,
+                   GTK_FILL_Y,
+                   0, 10, 10, 0, 0);
+
+    side_pack = gtk_packer_new();
+    gtk_container_add(GTK_CONTAINER(side_frame), side_pack);
+    
+    button_top = gtk_toggle_button_new_with_label("Top");
+    button_bottom = gtk_toggle_button_new_with_label("Bottom");
+    button_left = gtk_toggle_button_new_with_label("Left");
+    button_right = gtk_toggle_button_new_with_label("Right");
+
+    gtk_object_set_data(GTK_OBJECT(button_top), "side", (gpointer) GTK_SIDE_TOP);
+    gtk_object_set_data(GTK_OBJECT(button_bottom), "side", (gpointer) GTK_SIDE_BOTTOM);
+    gtk_object_set_data(GTK_OBJECT(button_left), "side", (gpointer) GTK_SIDE_LEFT);
+    gtk_object_set_data(GTK_OBJECT(button_right), "side", (gpointer) GTK_SIDE_RIGHT);
+
+    gtk_widget_set_usize(button_top, 50, -1);
+    gtk_widget_set_usize(button_bottom, 50, -1);
+    gtk_widget_set_usize(button_left, 50, -1);
+    gtk_widget_set_usize(button_right, 50, -1);
+    gtk_packer_add(GTK_PACKER(side_pack),
+                   button_top,
+                   GTK_SIDE_TOP,
+                   GTK_ANCHOR_CENTER,
+                   0,
+                   0, 5, 5, 0, 0);
+    gtk_packer_add(GTK_PACKER(side_pack),
+                   button_bottom,
+                   GTK_SIDE_BOTTOM,
+                   GTK_ANCHOR_CENTER,
+                   0,
+                   0, 5, 5, 0, 0);
+    gtk_packer_add(GTK_PACKER(side_pack),
+                   button_left,
+                   GTK_SIDE_LEFT,
+                   GTK_ANCHOR_CENTER,
+                   0,
+                   0, 10, 5, 0, 0);
+    gtk_packer_add(GTK_PACKER(side_pack),
+                   button_right,
+                   GTK_SIDE_RIGHT,
+                   GTK_ANCHOR_CENTER,
+                   0,
+                   0, 10, 5, 0, 0);
+    gtk_signal_connect (GTK_OBJECT (button_top), "toggled",
+                        GTK_SIGNAL_FUNC (toggle_side), (gpointer) info);
+    gtk_signal_connect (GTK_OBJECT (button_bottom), "toggled",
+                        GTK_SIGNAL_FUNC (toggle_side), (gpointer) info);
+    gtk_signal_connect (GTK_OBJECT (button_left), "toggled",
+                        GTK_SIGNAL_FUNC (toggle_side), (gpointer) info);
+    gtk_signal_connect (GTK_OBJECT (button_right), "toggled",
+                        GTK_SIGNAL_FUNC (toggle_side), (gpointer) info);
+
+    anchor_frame = gtk_frame_new("Anchor");
+    gtk_packer_add(GTK_PACKER(window_pack),
+                   anchor_frame,
+                   GTK_SIDE_LEFT,
+                   GTK_ANCHOR_W,
+                   GTK_FILL_Y,
+                   0, 10, 10, 0, 0);
+
+    anchor_pack = gtk_packer_new();
+    gtk_container_add(GTK_CONTAINER(anchor_frame), anchor_pack);
+
+    anchor_table = gtk_table_new(3,3,TRUE);
+    gtk_packer_add(GTK_PACKER(anchor_pack),
+                   anchor_table,
+                   GTK_SIDE_TOP,
+                   GTK_ANCHOR_CENTER,
+                   GTK_FILL_Y | GTK_FILL_X | GTK_PACK_EXPAND,
+                   0, 10, 5, 0, 0);
+
+    button_n = gtk_toggle_button_new_with_label("N");
+    button_s = gtk_toggle_button_new_with_label("S");
+    button_w = gtk_toggle_button_new_with_label("W");
+    button_e = gtk_toggle_button_new_with_label("E");
+    button_ne = gtk_toggle_button_new_with_label("NE");
+    button_nw = gtk_toggle_button_new_with_label("NW");
+    button_se = gtk_toggle_button_new_with_label("SE");
+    button_sw = gtk_toggle_button_new_with_label("SW");
+    button_center = gtk_toggle_button_new_with_label("");
+
+    gtk_object_set_data(GTK_OBJECT(button_n), "anchor", (gpointer) GTK_ANCHOR_N);
+    gtk_object_set_data(GTK_OBJECT(button_nw), "anchor", (gpointer) GTK_ANCHOR_NW);
+    gtk_object_set_data(GTK_OBJECT(button_ne), "anchor", (gpointer) GTK_ANCHOR_NE);
+    gtk_object_set_data(GTK_OBJECT(button_s), "anchor", (gpointer) GTK_ANCHOR_S);
+    gtk_object_set_data(GTK_OBJECT(button_sw), "anchor", (gpointer) GTK_ANCHOR_SW);
+    gtk_object_set_data(GTK_OBJECT(button_se), "anchor", (gpointer) GTK_ANCHOR_SE);
+    gtk_object_set_data(GTK_OBJECT(button_w), "anchor", (gpointer) GTK_ANCHOR_W);
+    gtk_object_set_data(GTK_OBJECT(button_e), "anchor", (gpointer) GTK_ANCHOR_E);
+    gtk_object_set_data(GTK_OBJECT(button_center), "anchor", (gpointer) GTK_ANCHOR_CENTER);
+
+    gtk_signal_connect (GTK_OBJECT (button_n), "toggled",
+                        GTK_SIGNAL_FUNC (toggle_anchor), (gpointer) info);
+    gtk_signal_connect (GTK_OBJECT (button_nw), "toggled",
+                        GTK_SIGNAL_FUNC (toggle_anchor), (gpointer) info);
+    gtk_signal_connect (GTK_OBJECT (button_ne), "toggled",
+                        GTK_SIGNAL_FUNC (toggle_anchor), (gpointer) info);
+    gtk_signal_connect (GTK_OBJECT (button_s), "toggled",
+                        GTK_SIGNAL_FUNC (toggle_anchor), (gpointer) info);
+    gtk_signal_connect (GTK_OBJECT (button_sw), "toggled",
+                        GTK_SIGNAL_FUNC (toggle_anchor), (gpointer) info);
+    gtk_signal_connect (GTK_OBJECT (button_se), "toggled",
+                        GTK_SIGNAL_FUNC (toggle_anchor), (gpointer) info);
+    gtk_signal_connect (GTK_OBJECT (button_w), "toggled",
+                        GTK_SIGNAL_FUNC (toggle_anchor), (gpointer) info);
+    gtk_signal_connect (GTK_OBJECT (button_e), "toggled",
+                        GTK_SIGNAL_FUNC (toggle_anchor), (gpointer) info);
+    gtk_signal_connect (GTK_OBJECT (button_center), "toggled",
+                        GTK_SIGNAL_FUNC (toggle_anchor), (gpointer) info);
+
+    gtk_table_attach_defaults(GTK_TABLE(anchor_table),
+                              button_nw,
+                              0, 1, 0, 1);
+    gtk_table_attach_defaults(GTK_TABLE(anchor_table),
+                              button_n,
+                              1, 2, 0, 1);
+    gtk_table_attach_defaults(GTK_TABLE(anchor_table),
+                              button_ne,
+                              2, 3, 0, 1);
+    gtk_table_attach_defaults(GTK_TABLE(anchor_table),
+                              button_w,
+                              0, 1, 1, 2);
+    gtk_table_attach_defaults(GTK_TABLE(anchor_table),
+                              button_center,
+                              1, 2, 1, 2);
+    gtk_table_attach_defaults(GTK_TABLE(anchor_table),
+                              button_e,
+                              2, 3, 1, 2);
+    gtk_table_attach_defaults(GTK_TABLE(anchor_table),
+                              button_sw,
+                              0, 1, 2, 3);
+    gtk_table_attach_defaults(GTK_TABLE(anchor_table),
+                              button_s,
+                              1, 2, 2, 3);
+    gtk_table_attach_defaults(GTK_TABLE(anchor_table),
+                              button_se,
+                              2, 3, 2, 3);
+
+    options_frame = gtk_frame_new("Options");
+    gtk_packer_add(GTK_PACKER(window_pack),
+                   options_frame,
+                   GTK_SIDE_LEFT,
+                   GTK_ANCHOR_W,
+                   GTK_FILL_Y,
+                   0, 10, 10, 0, 0);
+
+    options_pack = gtk_packer_new();
+    gtk_container_add(GTK_CONTAINER(options_frame), options_pack);
+
+    button_fillx = gtk_toggle_button_new_with_label("Fill X");
+    button_filly = gtk_toggle_button_new_with_label("Fill Y");
+    button_expand = gtk_toggle_button_new_with_label("Expand");
+
+    gtk_packer_add(GTK_PACKER(options_pack),
+                   button_fillx,
+                   GTK_SIDE_TOP,
+                   GTK_ANCHOR_N,
+                   GTK_FILL_X | GTK_PACK_EXPAND,
+                   0, 10, 5, 0, 0);
+    gtk_packer_add(GTK_PACKER(options_pack),
+                   button_filly,
+                   GTK_SIDE_TOP,
+                   GTK_ANCHOR_CENTER,
+                   GTK_FILL_X | GTK_PACK_EXPAND,
+                   0, 10, 5, 0, 0);
+    gtk_packer_add(GTK_PACKER(options_pack),
+                   button_expand,
+                   GTK_SIDE_TOP,
+                   GTK_ANCHOR_S,
+                   GTK_FILL_X | GTK_PACK_EXPAND,
+                   0, 10, 5, 0, 0);
+
+    gtk_object_set_data(GTK_OBJECT(button_fillx), "option", (gpointer) GTK_FILL_X);
+    gtk_object_set_data(GTK_OBJECT(button_filly), "option", (gpointer) GTK_FILL_Y);
+    gtk_object_set_data(GTK_OBJECT(button_expand), "option", (gpointer) GTK_PACK_EXPAND);
+
+    gtk_signal_connect (GTK_OBJECT (button_fillx), "toggled",
+                        GTK_SIGNAL_FUNC (toggle_options), (gpointer) info);
+    gtk_signal_connect (GTK_OBJECT (button_filly), "toggled",
+                        GTK_SIGNAL_FUNC (toggle_options), (gpointer) info);
+    gtk_signal_connect (GTK_OBJECT (button_expand), "toggled",
+                        GTK_SIGNAL_FUNC (toggle_options), (gpointer) info);
+
+
+
+    info->widgets = NULL;
+    info->packer = packer;
+    info->button_top = button_top;
+    info->button_bottom = button_bottom;
+    info->button_left = button_left;
+    info->button_right = button_right;
+    info->button_n = button_n;
+    info->button_nw = button_nw;
+    info->button_ne = button_ne;
+    info->button_e = button_e;
+    info->button_w = button_w;
+    info->button_center = button_center;
+    info->button_s = button_s;
+    info->button_sw = button_sw;
+    info->button_se = button_se;
+    info->button_fillx = button_fillx;
+    info->button_filly = button_filly;
+    info->button_expand = button_expand;
+
+    add_widget(NULL, (gpointer) info);
+
+    gtk_widget_show_all(window);
+
+    gtk_main();
+
+    return 0;
+}
+
+void 
+toggle_options (GtkWidget *widget, gpointer data)
+{
+   Info *info;
+   gint option;
+   GList *list;
+   GtkPackerChild *pchild;
+   gint fillx, filly, expand;
+
+   info = (Info*) data;
+   option = (gint) gtk_object_get_data(GTK_OBJECT(widget), "option");
+
+   pchild = info->pchild;
+   if (pchild == NULL) {
+       abort();
+   };
+
+   fillx = filly = expand = 0;
+
+   if (GTK_TOGGLE_BUTTON(info->button_fillx)->active)
+       fillx = GTK_FILL_X;
+   if (GTK_TOGGLE_BUTTON(info->button_filly)->active)
+       filly = GTK_FILL_Y;
+   if (GTK_TOGGLE_BUTTON(info->button_expand)->active)
+       expand = GTK_PACK_EXPAND;
+
+   gtk_packer_configure(GTK_PACKER(info->packer),
+                        info->current,
+                        pchild->side,
+                        pchild->anchor,
+                        fillx | filly | expand, 
+                        pchild->border_width, 
+                        pchild->padX, 
+                        pchild->padY, 
+                        pchild->iPadX, 
+                        pchild->iPadY);
+}
+
+void 
+toggle_anchor (GtkWidget *widget, gpointer data)
+{
+   Info *info;
+   gint anchor;
+   GList *list;
+   GtkPackerChild *pchild;
+
+   info = (Info*) data;
+   if (GTK_TOGGLE_BUTTON(widget)->active) {
+       anchor = (gint) gtk_object_get_data(GTK_OBJECT(widget), "anchor");
+
+       pchild = info->pchild;
+       if (pchild == NULL) {
+           abort();
+       };
+
+       gtk_packer_configure(GTK_PACKER(info->packer),
+                           info->current,
+                           pchild->side,
+                           anchor,
+                           pchild->options, 
+                           pchild->border_width, 
+                           pchild->padX, 
+                           pchild->padY, 
+                           pchild->iPadX, 
+                           pchild->iPadY);
+
+       if (info->button_n != widget) {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_n),0);
+           gtk_widget_set_sensitive(info->button_n, 1);
+       }
+       if (info->button_nw != widget) {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_nw),0);
+           gtk_widget_set_sensitive(info->button_nw, 1);
+       }
+       if (info->button_ne != widget) {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_ne),0);
+           gtk_widget_set_sensitive(info->button_ne, 1);
+       }
+       if (info->button_s != widget) {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_s),0);
+           gtk_widget_set_sensitive(info->button_s, 1);
+       }
+       if (info->button_sw != widget) {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_sw),0);
+           gtk_widget_set_sensitive(info->button_sw, 1);
+       }
+       if (info->button_se != widget) {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_se),0);
+           gtk_widget_set_sensitive(info->button_se, 1);
+       }
+       if (info->button_e != widget) {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_e),0);
+           gtk_widget_set_sensitive(info->button_e, 1);
+       }
+       if (info->button_w != widget) {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_w),0);
+           gtk_widget_set_sensitive(info->button_w, 1);
+       }
+       if (info->button_center != widget) {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_center),0);
+           gtk_widget_set_sensitive(info->button_center, 1);
+       }
+
+       gtk_widget_set_sensitive(widget, 0);
+    }
+}
+
+void 
+toggle_side (GtkWidget *widget, gpointer data)
+{
+   Info *info;
+   gint side;
+   GList *list;
+   GtkPackerChild *pchild;
+
+   info = (Info*) data;
+   if (GTK_TOGGLE_BUTTON(widget)->active) {
+
+       side = (gint) gtk_object_get_data(GTK_OBJECT(widget), "side");
+
+       pchild = info->pchild;
+       if (pchild == NULL) {
+           abort();
+       };
+       gtk_packer_configure(GTK_PACKER(info->packer),
+                           info->current,
+                           side,
+                           pchild->anchor,
+                           pchild->options, 
+                           pchild->border_width, 
+                           pchild->padX, 
+                           pchild->padY, 
+                           pchild->iPadX, 
+                           pchild->iPadY);
+
+       if (info->button_top != widget) {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_top),0);
+           gtk_widget_set_sensitive(info->button_top, 1);
+       }
+
+       if (info->button_bottom != widget) {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_bottom),0);
+           gtk_widget_set_sensitive(info->button_bottom, 1);
+       }
+
+       if (info->button_left != widget) {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_left),0);
+           gtk_widget_set_sensitive(info->button_left, 1);
+       }
+
+       if (info->button_right != widget) {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_right),0);
+           gtk_widget_set_sensitive(info->button_right, 1);
+       }
+
+       gtk_widget_set_sensitive(widget, 0);
+    }
+}
+
+void
+set_widget (GtkWidget *w, gpointer data) {
+   Info *info;
+   GList *list;
+   GtkWidget *widget;
+   GtkPackerChild *pchild;
+   gint options;
+
+   if (GTK_TOGGLE_BUTTON(w)->active) {
+
+       info = (Info*) data;
+       info->current = w;
+
+       pchild = NULL;
+       list = g_list_first(GTK_PACKER(info->packer)->children);
+       while (list) {
+           if (((GtkPackerChild*)(list->data))->widget == info->current) {
+               pchild = (GtkPackerChild*)(list->data);
+               break;
+           }
+           list = g_list_next(list);
+       }
+       if (pchild == NULL) {
+           abort();
+       };
+
+       info->pchild = pchild;
+       switch (pchild->side) {
+         case GTK_SIDE_TOP:
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_top),1);
+           break;
+         case GTK_SIDE_BOTTOM:
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_bottom),1);
+           break;
+         case GTK_SIDE_LEFT:
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_left),1);
+           break;
+         case GTK_SIDE_RIGHT:
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_right),1);
+           break;
+         default:
+           printf("foo... side == %d\n", pchild->side);
+       };
+
+       switch (pchild->anchor) {
+         case GTK_ANCHOR_N:
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_n),1);
+           break;
+         case GTK_ANCHOR_NW:
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_nw),1);
+           break;
+         case GTK_ANCHOR_NE:
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_ne),1);
+           break;
+         case GTK_ANCHOR_S:
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_s),1);
+           break;
+         case GTK_ANCHOR_SW:
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_sw),1);
+           break;
+         case GTK_ANCHOR_SE:
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_se),1);
+           break;
+         case GTK_ANCHOR_W:
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_w),1);
+           break;
+         case GTK_ANCHOR_E:
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_e),1);
+           break;
+         case GTK_ANCHOR_CENTER:
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_center),1);
+           break;
+         default:
+       };
+
+       options = pchild->options;
+       if (options & GTK_PACK_EXPAND) {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_expand),1);
+       } else {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_expand),0);
+       }
+       if (options & GTK_FILL_X) {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_fillx),1);
+       } else {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_fillx),0);
+       }
+       if (options & GTK_FILL_Y) {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_filly),1);
+       } else {
+           gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(info->button_filly),0);
+       }
+       
+
+       gtk_widget_set_sensitive(w, 0);
+
+       list = g_list_first(info->widgets);
+       while (list) {
+           widget = (GtkWidget*)(list->data);
+           if (widget != info->current) {
+               gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widget),0);
+               gtk_widget_set_sensitive(widget, 1);
+           }
+
+           list = g_list_next(list);
+       } 
+   }
+
+}
+
+void 
+add_widget (GtkWidget *w, gpointer data)
+{  
+   static gint n = 0;
+   GtkPacker *packer;
+   GtkWidget *widget;
+   gchar str[255];
+   Info *info;
+
+   info = (Info*) data;
+   packer = GTK_PACKER(info->packer);
+   
+   sprintf(str, "%d", n);
+   widget = gtk_toggle_button_new_with_label(str);
+   gtk_widget_set_usize(widget, 50, 50);
+   gtk_container_add(GTK_CONTAINER(packer), widget);
+   gtk_widget_show(widget);
+
+   gtk_signal_connect (GTK_OBJECT (widget), "toggled",
+                       GTK_SIGNAL_FUNC (set_widget), (gpointer) info);
+
+   info->widgets = g_list_append(info->widgets, (gpointer) widget);
+   gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widget),1);
+   set_widget(widget, info);
+
+   n++;
+}
+
index 3d64c2f7b3a279b254e50fc55c6ef41a5b98eca0..d6503478d7f483df7d6c5cc5028f69737ae1ce15 100644 (file)
@@ -61,6 +61,7 @@ libgtk_1_1_la_SOURCES = \
        gtknotebook.c           \
        gtkobject.c             \
        gtkoptionmenu.c         \
+       gtkpacker.c             \
        gtkpaned.c              \
        gtkpixmap.c             \
        gtkpreview.c            \
@@ -162,6 +163,7 @@ gtkinclude_HEADERS = \
        gtknotebook.h           \
        gtkobject.h             \
        gtkoptionmenu.h         \
+       gtkpacker.h             \
        gtkpaned.h              \
        gtkpixmap.h             \
        gtkpreview.h            \
index 7c5aca4919eb251c7f0eb57ca45e9a0b11d5b30c..785eed475d17b7b564b3ac8878cd0d4b531cec1c 100644 (file)
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -78,6 +78,7 @@
 #include <gtk/gtknotebook.h>
 #include <gtk/gtkobject.h>
 #include <gtk/gtkoptionmenu.h>
+#include <gtk/gtkpacker.h>
 #include <gtk/gtkpaned.h>
 #include <gtk/gtkpixmap.h>
 #include <gtk/gtkpreview.h>
diff --git a/gtk/gtkpacker.c b/gtk/gtkpacker.c
new file mode 100644 (file)
index 0000000..4d39f76
--- /dev/null
@@ -0,0 +1,878 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ * 
+ * GtkPacker Widget 
+ * Copyright (C) 1998 Shawn T. Amundson, James S. Mitchell, Michael L. Staiger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+/* 
+ * This file contains modified code derived from Tk 8.0.  Below is the header of
+ * the relevant file.  The file 'license.terms' is included inline below.
+ * 
+ * tkPack.c --
+ *
+ *      This file contains code to implement the "packer"
+ *      geometry manager for Tk.
+ *
+ * Copyright (c) 1990-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1995 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * SCCS: @(#) tkPack.c 1.64 96/05/03 10:51:52
+ *
+ * The file license.terms is below.  NOTE: THE FOLLOWING APPLIES ONLY TO
+ * PORTIONS DERIVED FROM TK 8.0.  THE LICENSE FOR THIS FILE IS LGPL, AS
+ * STATED ABOVE AND ALLOWED BELOW.  
+-- BEGIN license.terms --
+This software is copyrighted by the Regents of the University of
+California, Sun Microsystems, Inc., and other parties.  The following
+terms apply to all files associated with the software unless explicitly
+disclaimed in individual files.
+
+The authors hereby grant permission to use, copy, modify, distribute,
+and license this software and its documentation for any purpose, provided
+that existing copyright notices are retained in all copies and that this
+notice is included verbatim in any distributions. No written agreement,
+license, or royalty fee is required for any of the authorized uses.
+Modifications to this software may be copyrighted by their authors
+and need not follow the licensing terms described here, provided that
+the new terms are clearly indicated on the first page of each file where
+they apply.
+
+IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
+IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+MODIFICATIONS.
+
+GOVERNMENT USE: If you are acquiring this software on behalf of the
+U.S. government, the Government shall have only "Restricted Rights"
+in the software and related documentation as defined in the Federal 
+Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you
+are acquiring the software on behalf of the Department of Defense, the
+software shall be classified as "Commercial Computer Software" and the
+Government shall have only "Restricted Rights" as defined in Clause
+252.227-7013 (c) (1) of DFARs.  Notwithstanding the foregoing, the
+authors grant the U.S. Government and others acting in its behalf
+permission to use and distribute the software in accordance with the
+terms specified in this license.
+-- END license.terms --
+ *
+ */
+
+
+#include "gtkpacker.h"
+
+
+static void gtk_packer_class_init    (GtkPackerClass   *klass);
+static void gtk_packer_init          (GtkPacker        *packer);
+static void gtk_packer_map           (GtkWidget        *widget);
+static void gtk_packer_unmap         (GtkWidget        *widget);
+static void gtk_packer_draw          (GtkWidget        *widget,
+                                      GdkRectangle     *area);
+static gint gtk_packer_expose        (GtkWidget        *widget,
+                                      GdkEventExpose   *event);
+static void gtk_packer_size_request  (GtkWidget      *widget,
+                                      GtkRequisition *requisition);
+static void gtk_packer_size_allocate (GtkWidget      *widget,
+                                      GtkAllocation  *allocation);
+static void gtk_packer_container_add (GtkContainer   *container,
+                                      GtkWidget      *child);
+static void gtk_packer_remove        (GtkContainer   *container,
+                                      GtkWidget      *widget);
+static void gtk_packer_foreach       (GtkContainer   *container,
+                                      GtkCallback     callback,
+                                      gpointer        callback_data);
+
+
+static GtkPackerClass *parent_class;
+
+GtkType
+gtk_packer_get_type (void)
+{
+  static GtkType packer_type = 0;
+
+  if (!packer_type)
+    {
+      GtkTypeInfo packer_info =
+      {
+        "GtkPacker",
+        sizeof (GtkPacker),
+        sizeof (GtkPackerClass),
+        (GtkClassInitFunc) gtk_packer_class_init,
+        (GtkObjectInitFunc) gtk_packer_init,
+        (GtkArgSetFunc) NULL,
+        (GtkArgGetFunc) NULL
+      };
+
+      packer_type = gtk_type_unique (gtk_container_get_type (), &packer_info);
+    }
+  
+  return packer_type;
+}
+
+static void
+gtk_packer_class_init (GtkPackerClass *klass)
+{
+  GtkWidgetClass *widget_class;
+  GtkContainerClass *container_class;
+  
+  widget_class = (GtkWidgetClass*) klass;
+  container_class = (GtkContainerClass*) klass;
+  parent_class = gtk_type_class (gtk_container_get_type ());
+  
+  widget_class->map = gtk_packer_map;
+  widget_class->unmap = gtk_packer_unmap;
+  widget_class->draw = gtk_packer_draw;
+  widget_class->expose_event = gtk_packer_expose;
+  
+  widget_class->size_request = gtk_packer_size_request;
+  widget_class->size_allocate = gtk_packer_size_allocate;
+  
+  container_class->add = gtk_packer_container_add;
+  container_class->remove = gtk_packer_remove;
+  container_class->foreach = gtk_packer_foreach; 
+  
+}
+
+
+static void
+gtk_packer_init (GtkPacker *packer)
+{
+  GTK_WIDGET_SET_FLAGS (packer, GTK_NO_WINDOW | GTK_BASIC);
+  
+  packer->children = NULL;
+  packer->spacing = 0;
+}
+
+void
+gtk_packer_set_spacing (GtkPacker *packer, gint spacing)
+{
+  g_return_if_fail (packer != NULL);
+  g_return_if_fail (GTK_IS_PACKER (packer));
+  
+  if (spacing != packer->spacing) 
+    {
+      packer->spacing = spacing;
+      gtk_widget_queue_resize(GTK_WIDGET(packer));
+    }
+};
+
+GtkWidget*
+gtk_packer_new (void)
+{
+  return GTK_WIDGET (gtk_type_new (gtk_packer_get_type ()));
+}
+
+static void
+redo_defaults_children (GtkPacker *packer) {
+  GList *list;
+  GtkPackerChild *child;
+  
+  list = g_list_first(packer->children);
+  while (list != NULL) 
+    {
+      child = list->data;
+      
+      if (child->use_default) 
+       {
+         child->border_width = packer->default_border_width;
+         child->padX = packer->default_padX;
+         child->padY = packer->default_padY;
+         child->iPadX = packer->default_iPadX;
+         child->iPadY = packer->default_iPadY;
+         gtk_widget_queue_resize(GTK_WIDGET(packer));
+       }
+      list = g_list_next(list);
+    }
+}
+
+void
+gtk_packer_set_default_border_width (GtkPacker *packer, gint border)
+{
+  g_return_if_fail (packer != NULL);
+  g_return_if_fail (GTK_IS_PACKER (packer));
+  
+  if (packer->default_border_width != border) 
+    {
+      packer->default_border_width = border;;
+      redo_defaults_children(packer);
+    }
+}
+void
+gtk_packer_set_default_pad(GtkPacker *packer, gint padX ,gint padY)
+{
+  g_return_if_fail (packer != NULL);
+  g_return_if_fail (GTK_IS_PACKER (packer));
+  
+  if (packer->default_padX != padX ||
+      packer->default_padY != padY) 
+    {
+      packer->default_padX = padX;;
+      packer->default_padY = padY;;
+      redo_defaults_children(packer);
+    }
+}
+
+void
+gtk_packer_set_default_ipad(GtkPacker *packer, gint iPadX ,gint iPadY)
+{
+  g_return_if_fail (packer != NULL);
+  g_return_if_fail (GTK_IS_PACKER (packer));
+  
+  if (packer->default_iPadX != iPadX ||
+      packer->default_iPadY != iPadY) {
+    
+    packer->default_iPadX = iPadX;;
+    packer->default_iPadY = iPadY;;
+    redo_defaults_children(packer);
+  }
+}
+
+static void 
+gtk_packer_container_add (GtkContainer *packer, GtkWidget *child)
+{
+  gtk_packer_add_defaults(GTK_PACKER(packer), child,
+                         GTK_SIDE_TOP, GTK_ANCHOR_CENTER, 0);
+}
+
+void 
+gtk_packer_add_defaults (GtkPacker *packer, GtkWidget *child,
+                         GtkSide          side,
+                         GtkAnchor        anchor,
+                         GtkPackerOptions options)
+{
+  GtkPackerChild *pchild;
+  
+  g_return_if_fail (packer != NULL);
+  g_return_if_fail (GTK_IS_PACKER (packer));
+  g_return_if_fail (child != NULL);
+  
+  pchild = (GtkPackerChild*) g_malloc(sizeof(GtkPackerChild));
+  
+  pchild->widget = child;
+  pchild->side = side;
+  pchild->options = options;
+  pchild->anchor = anchor;
+  
+  pchild->use_default = 1;
+  
+  pchild->border_width = packer->default_border_width;
+  pchild->padX = packer->default_padX;
+  pchild->padY = packer->default_padY;
+  pchild->iPadX = packer->default_iPadX;
+  pchild->iPadY = packer->default_iPadY;
+  
+  packer->children = g_list_append(packer->children, (gpointer) pchild);
+  
+  gtk_widget_set_parent (child, GTK_WIDGET (packer));
+  
+  if (GTK_WIDGET_VISIBLE (GTK_WIDGET (packer))) 
+    {
+      if (GTK_WIDGET_REALIZED (GTK_WIDGET (packer)) &&
+          !GTK_WIDGET_REALIZED (child)) 
+        gtk_widget_realize (child);
+      
+      if (GTK_WIDGET_MAPPED (GTK_WIDGET (packer)) &&
+          !GTK_WIDGET_MAPPED (child)) 
+        gtk_widget_map (child);
+    }
+
+  if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (packer))
+    gtk_widget_queue_resize (child);
+  
+}
+
+void 
+gtk_packer_add (GtkPacker        *packer,
+                GtkWidget        *child,
+                GtkSide          side,
+                GtkAnchor        anchor,
+                GtkPackerOptions options,
+                gint border_width,
+                gint padX,
+                gint padY,
+                gint iPadX,
+                gint iPadY)
+{
+  GtkPackerChild *pchild;
+  
+  g_return_if_fail (packer != NULL);
+  g_return_if_fail (GTK_IS_PACKER (packer));
+  g_return_if_fail (child != NULL);
+  
+  pchild = (GtkPackerChild*) g_malloc(sizeof(GtkPackerChild));
+  
+  pchild->widget = child;
+  pchild->side = side;
+  pchild->options = options;
+  pchild->anchor = anchor;
+  
+  pchild->use_default = 0;
+  
+  pchild->border_width = border_width;
+  pchild->padX = padX;
+  pchild->padY = padY;
+  pchild->iPadX = iPadX;
+  pchild->iPadY = iPadY;
+  
+  packer->children = g_list_append(packer->children, (gpointer) pchild);
+  
+  gtk_widget_set_parent (child, GTK_WIDGET (packer));
+  
+  if (GTK_WIDGET_VISIBLE (GTK_WIDGET (packer))) 
+    {
+      if (GTK_WIDGET_REALIZED (GTK_WIDGET (packer)) &&
+          !GTK_WIDGET_REALIZED (child)) 
+        gtk_widget_realize (child);
+      
+      if (GTK_WIDGET_MAPPED (GTK_WIDGET (packer)) &&
+          !GTK_WIDGET_MAPPED (child)) 
+        gtk_widget_map (child);
+    }
+  
+  if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (packer))
+    gtk_widget_queue_resize (child);
+  
+}
+
+void
+gtk_packer_configure (GtkPacker        *packer,
+                      GtkWidget        *child,
+                      GtkSide          side,
+                      GtkAnchor        anchor,
+                      GtkPackerOptions options,
+                      gint border_width,
+                      gint padX,
+                      gint padY,
+                      gint ipadX,
+                      gint ipadY)
+{
+  GList *list;
+  GtkPackerChild *pchild;
+  
+  g_return_if_fail (packer != NULL);
+  g_return_if_fail (GTK_IS_PACKER (packer));
+  g_return_if_fail (child != NULL);
+  
+  list = g_list_first(packer->children);
+  while (list != NULL) 
+    {
+      pchild = (GtkPackerChild*) list->data;
+      if (pchild->widget == child) 
+       {
+         pchild->side = side;
+         pchild->anchor = anchor;
+         pchild->options = options;
+         
+         pchild->use_default = 0;
+         
+         pchild->border_width = border_width;
+         pchild->padX = padX;
+         pchild->padY = padY;
+         pchild->iPadX = ipadX;
+         pchild->iPadY = ipadY;
+         
+         if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (packer))
+           gtk_widget_queue_resize (child);
+         return;
+        }
+      list = g_list_next(list);
+    }
+
+  g_warning ("gtk_packer_configure(): couldn't find child `%s' amongst the packer's children", gtk_type_name (GTK_OBJECT_TYPE (child)));
+
+}
+
+static void 
+gtk_packer_remove (GtkContainer *container, GtkWidget *widget) 
+{
+  GtkPacker *packer;
+  GtkPackerChild *child;
+  GList *children;
+  gint visible;
+  
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (widget != NULL);
+  
+  packer = GTK_PACKER (container);
+  
+  children = g_list_first(packer->children);
+  while (children) 
+    {
+      child = children->data;
+      
+      if (child->widget == widget) 
+       {
+         visible = GTK_WIDGET_VISIBLE (widget);
+         gtk_widget_unparent (widget);
+         
+         packer->children = g_list_remove_link (packer->children, children);
+         g_list_free (children);
+         g_free (child);
+         
+         if (visible && GTK_WIDGET_VISIBLE (container))
+           gtk_widget_queue_resize (GTK_WIDGET (container));
+         
+         break;
+        }
+      
+      children = g_list_next(children);
+    }
+}
+
+static void 
+gtk_packer_map (GtkWidget *widget)
+{
+  GtkPacker *packer;
+  GtkPackerChild *child;
+  GList *children;
+  
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PACKER (widget));
+  
+  packer = GTK_PACKER (widget);
+  GTK_WIDGET_SET_FLAGS (packer, GTK_MAPPED);
+  
+  children = g_list_first(packer->children);
+  while (children != NULL) 
+    {
+      child = children->data;
+      children = g_list_next(children);
+      
+      if (GTK_WIDGET_VISIBLE (child->widget) &&
+         !GTK_WIDGET_MAPPED (child->widget))
+       gtk_widget_map (child->widget);
+    }
+}
+
+static void 
+gtk_packer_unmap (GtkWidget *widget)
+{
+  GtkPacker *packer;
+  GtkPackerChild *child;
+  GList *children;
+  
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PACKER (widget));
+  
+  packer = GTK_PACKER (widget);
+  GTK_WIDGET_UNSET_FLAGS (packer, GTK_MAPPED);
+  
+  children = g_list_first(packer->children);
+  while (children) 
+    {
+      child = children->data;
+      children = g_list_next(children);
+      
+      if (GTK_WIDGET_VISIBLE (child->widget) &&
+         GTK_WIDGET_MAPPED (child->widget))
+       gtk_widget_unmap (child->widget);
+    }
+}
+
+static void 
+gtk_packer_draw (GtkWidget *widget, GdkRectangle     *area)
+{
+  GtkPacker *packer;
+  GtkPackerChild *child;
+  GdkRectangle child_area;
+  GList *children;
+
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PACKER (widget));
+  if (GTK_WIDGET_DRAWABLE (widget)) 
+    {
+      packer = GTK_PACKER (widget);
+      
+      children = g_list_first(packer->children);
+      while (children != NULL) 
+       {
+         child = children->data;
+         children = g_list_next(children);
+         
+         if (gtk_widget_intersect (child->widget, area, &child_area))
+           gtk_widget_draw (child->widget, &child_area);
+        }
+    }
+  
+}
+
+static gint 
+gtk_packer_expose (GtkWidget *widget, GdkEventExpose *event)
+{
+  GtkPacker *packer;
+  GtkPackerChild *child;
+  GdkEventExpose child_event;
+  GList *children;
+  
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_PACKER (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
+  
+  if (GTK_WIDGET_DRAWABLE (widget)) 
+    {
+      packer = GTK_PACKER (widget);
+      
+      child_event = *event;
+      
+      children = g_list_first(packer->children);
+      while (children) 
+       {
+         child = children->data;
+         children = g_list_next(children);
+         
+         if (GTK_WIDGET_NO_WINDOW (child->widget) &&
+             gtk_widget_intersect (child->widget, &event->area, &child_event.area))
+           gtk_widget_event (child->widget, (GdkEvent*) &child_event);
+       }
+    }   
+  
+  return FALSE;
+}
+
+static void 
+gtk_packer_size_request (GtkWidget *widget, GtkRequisition *requisition)
+{
+  GtkPacker *packer;
+  GtkPackerChild *child;
+  GList *children;
+  gint nvis_vert_children;
+  gint nvis_horz_children;
+  gint width, height;
+  gint maxWidth, maxHeight;
+  
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PACKER (widget));
+  g_return_if_fail (requisition != NULL);
+  
+  packer = GTK_PACKER (widget);
+  requisition->width = 0;
+  requisition->height = 0;
+  nvis_vert_children = 0;
+  nvis_horz_children = 0;
+  
+  width = height = maxWidth = maxHeight = 0;
+  
+  children = g_list_first(packer->children);
+  while (children != NULL) 
+    {
+      child = children->data;
+      
+      if (GTK_WIDGET_VISIBLE (child->widget)) 
+       {
+         gtk_widget_size_request (child->widget, &child->widget->requisition);
+         
+         if((child->side == GTK_SIDE_TOP) || (child->side == GTK_SIDE_BOTTOM))
+           {
+             maxWidth = MAX(maxWidth, (child->widget->requisition.width 
+                                       + 2 * child->border_width 
+                                       + child->padX + child->iPadX 
+                                       + width));
+             height += child->widget->requisition.height 
+               + 2 * child->border_width 
+               + child->padY + child->iPadY;
+            } 
+         else 
+           {
+             maxHeight = MAX(maxHeight,(child->widget->requisition.height 
+                                        + 2 * child->border_width + 
+                                        child->padY + child->iPadY 
+                                        + height));
+             width += child->widget->requisition.width 
+               + 2 * child->border_width 
+               + child->padX + child->iPadX;
+            }
+        }
+
+      children = g_list_next(children);
+    }
+  requisition->width = MAX (maxWidth, width);
+  requisition->height = MAX (maxHeight, height);
+}
+
+static gint
+YExpansion (GList *children, gint cavityHeight)
+{
+  GList *list;
+  GtkPackerChild *child;
+  GtkWidget *widget;
+  gint numExpand, minExpand, curExpand;
+  gint childHeight;
+  
+  minExpand = cavityHeight;
+  numExpand = 0;
+  
+  list = children;
+  while (list != NULL) 
+    {
+      child = list->data;
+      widget = child->widget;
+      childHeight = widget->requisition.height + 2 * child->border_width +
+       child->iPadY + child->padY;
+      if ((child->side == GTK_SIDE_LEFT) || (child->side == GTK_SIDE_RIGHT)) 
+       {
+         curExpand = (cavityHeight - childHeight)/numExpand;
+         minExpand = MIN(minExpand, curExpand);
+        } 
+      else 
+       {
+         cavityHeight -= childHeight;
+         if (child->options & GTK_PACK_EXPAND)
+           numExpand++;
+        }
+      list = g_list_next(list);
+    } 
+  curExpand = cavityHeight/numExpand; 
+  if (curExpand < minExpand)
+    minExpand = curExpand;
+  return (minExpand < 0) ? 0 : minExpand;
+}
+
+static gint
+XExpansion (GList *children, gint cavityWidth)
+{
+  GList *list;
+  GtkPackerChild *child;
+  GtkWidget *widget;
+  gint numExpand, minExpand, curExpand;
+  gint childWidth;
+  
+  minExpand = cavityWidth;
+  numExpand = 0;
+  
+  list = children;
+  while (list != NULL) 
+    {
+      child = list->data;
+      widget = child->widget;
+      childWidth = widget->requisition.width + 2 * child->border_width 
+       + child->iPadX + child->padX;
+
+      if ((child->side == GTK_SIDE_TOP) || (child->side == GTK_SIDE_BOTTOM)) 
+       {
+         curExpand = (cavityWidth - childWidth)/numExpand;
+         minExpand = MIN(minExpand, curExpand); 
+        } 
+      else 
+       {
+         cavityWidth -= childWidth;
+         if (child->options & GTK_PACK_EXPAND)
+           numExpand++;
+        }
+      list = g_list_next(list);
+    } 
+  curExpand = cavityWidth/numExpand;
+  if (curExpand < minExpand)
+    minExpand = curExpand;
+  return (minExpand < 0) ? 0 : minExpand; 
+};
+
+static void 
+gtk_packer_size_allocate (GtkWidget *widget, GtkAllocation  *allocation)
+{
+  GtkPacker *packer;
+  GtkAllocation child_allocation;
+  GList *list;
+  GtkPackerChild *child;
+  gint cavityX, cavityY;
+  gint cavityWidth, cavityHeight;
+  gint width, height, x, y;
+  gint frameHeight, frameWidth, frameX, frameY;
+  gint borderX, borderY;
+  
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_PACKER (widget));
+  g_return_if_fail (allocation != NULL);
+
+  x = y = 0;
+
+  widget->allocation = *allocation;
+  packer = GTK_PACKER(widget);
+  
+  cavityX = widget->allocation.x;
+  cavityY = widget->allocation.y;
+  cavityWidth = widget->allocation.width;
+  cavityHeight = widget->allocation.height;
+  list = g_list_first(packer->children);
+  while (list != NULL)
+    {
+      child = list->data;
+      
+      if ((child->side == GTK_SIDE_TOP) || (child->side == GTK_SIDE_BOTTOM)) 
+       {
+         frameWidth = cavityWidth;
+         frameHeight = child->widget->requisition.height +
+           2 * child->border_width + child->padY + child->iPadY;
+         if (child->options & GTK_PACK_EXPAND)
+           frameHeight += YExpansion(list, cavityHeight);
+         cavityHeight -= frameHeight;
+         if (cavityHeight < 0) 
+           {
+             frameHeight += cavityHeight;
+             cavityHeight = 0;
+            }
+         frameX = cavityX;
+         if (child->side == GTK_SIDE_TOP) 
+           {
+             frameY = cavityY;
+             cavityY += frameHeight;
+            } 
+         else 
+           {
+             frameY = cavityY + cavityHeight;
+            }
+        } 
+      else 
+       {
+         frameHeight = cavityHeight;
+         frameWidth = child->widget->requisition.width + 
+           2 * child->border_width + child->padX + child->iPadX;
+         if (child->options & GTK_PACK_EXPAND)
+           frameWidth += XExpansion(list, cavityWidth);
+         cavityWidth -= frameWidth;
+         if (cavityWidth < 0) {
+           frameWidth += cavityWidth;
+           cavityWidth = 0;
+         }
+         frameY = cavityY;
+         if (child->side == GTK_SIDE_LEFT) 
+           {
+             frameX = cavityX;
+             cavityX += frameWidth;
+           } 
+         else 
+           {
+             frameX = cavityX + cavityWidth;
+            }
+        }
+
+      borderX = child->padX + 2 * child->border_width;
+      borderY = child->padY + 2 * child->border_width;
+
+      width = child->widget->requisition.width + 
+       2 * child->border_width + child->iPadX;
+      if ((child->options & GTK_FILL_X) || (width > (frameWidth - borderX)))
+       width = frameWidth - borderX;
+      height = child->widget->requisition.height + 
+       2 * child->border_width + child->iPadY;
+      
+      if ((child->options & GTK_FILL_Y) || (height > (frameHeight - borderY)))
+       height = frameHeight - borderY;
+      
+      borderX /= 2;
+      borderY /= 2;
+      switch (child->anchor) 
+       {
+       case GTK_ANCHOR_N:
+         x = frameX + (frameWidth - width)/2;
+         y = frameY + borderY;
+         break;
+       case GTK_ANCHOR_NE:
+         x = frameX + frameWidth - width - borderX;
+         y = frameY + borderY;
+         break;
+       case GTK_ANCHOR_E:
+         x = frameX + frameWidth - width - borderX;
+         y = frameY + (frameHeight - height)/2;
+         break;
+       case GTK_ANCHOR_SE:
+         x = frameX + frameWidth - width - borderX;
+         y = frameY + frameHeight - height - borderY;
+         break;
+       case GTK_ANCHOR_S:
+         x = frameX + (frameWidth - width)/2;
+         y = frameY + frameHeight - height - borderY;
+         break;
+       case GTK_ANCHOR_SW:
+         x = frameX + borderX;
+         y = frameY + frameHeight - height - borderY;
+         break;
+       case GTK_ANCHOR_W:
+         x = frameX + borderX;
+         y = frameY + (frameHeight - height)/2;
+         break;
+       case GTK_ANCHOR_NW:
+         x = frameX + borderX;
+         y = frameY + borderY;
+         break;
+       case GTK_ANCHOR_CENTER:
+         x = frameX + (frameWidth - width)/2;
+         y = frameY + (frameHeight - height)/2;
+         break;
+       default:
+         g_warning ("gtk_packer_size_allocate(): bad anchor type: %d", child->anchor);
+        } 
+        if (width <= 0 || height <= 0) 
+         {
+            gtk_widget_unmap(child->widget);
+         } 
+       else 
+         {
+           child_allocation.x = x;
+           child_allocation.y = y;
+           child_allocation.width = width;
+           child_allocation.height = height;
+           gtk_widget_size_allocate (child->widget, &child_allocation);
+           
+           if (GTK_WIDGET_MAPPED (widget) &&
+               !(GTK_WIDGET_MAPPED (child->widget)))
+             gtk_widget_map(child->widget); 
+         }
+       
+        list = g_list_next(list);
+    }
+}
+
+static void
+gtk_packer_foreach (GtkContainer *container,
+                    GtkCallback   callback,
+                    gpointer      callback_data)
+{
+  GtkPacker *packer;
+  GtkPackerChild *child;
+  GList *children;
+  
+  g_return_if_fail (container != NULL);
+  g_return_if_fail (GTK_IS_PACKER (container));
+  g_return_if_fail (callback != NULL);
+  
+  packer = GTK_PACKER (container);
+  
+  children = g_list_first(packer->children);
+  while (children != NULL) 
+    {
+      child = children->data;
+      children = g_list_next(children);
+      
+      (* callback) (child->widget, callback_data);
+    }
+}
+
diff --git a/gtk/gtkpacker.h b/gtk/gtkpacker.h
new file mode 100644 (file)
index 0000000..21617ba
--- /dev/null
@@ -0,0 +1,142 @@
+/* GTK - The GIMP Toolkit 
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald 
+ * 
+ * GtkPacker Widget 
+ * Copyright (C) 1998 Shawn T. Amundson, James S. Mitchell, Michael L. Staiger
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_PACKER_H__
+#define __GTK_PACKER_H__
+
+#include <gtk/gtkcontainer.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define GTK_TYPE_PACKER          (gtk_packer_get_type ())
+#define GTK_PACKER(obj)          (GTK_CHECK_CAST ((obj), GTK_TYPE_PACKER, GtkPacker))
+#define GTK_PACKER_CLASS(klass)  (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_PACKER, GtkPackerClass))
+#define GTK_IS_PACKER(obj)       (GTK_CHECK_TYPE ((obj), GTK_TYPE_PACKER))
+#define GTK_IS_PACKER_CLASS(klass)      (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PACKER))
+
+
+
+typedef struct _GtkPacker           GtkPacker;
+typedef struct _GtkPackerClass      GtkPackerClass;
+typedef struct _GtkPackerChild      GtkPackerChild;
+
+typedef enum {
+    GTK_PACK_EXPAND   = 1 << 0,
+    GTK_FILL_X        = 1 << 1,
+    GTK_FILL_Y        = 1 << 2
+} GtkPackerOptions;
+
+typedef enum {
+    GTK_SIDE_TOP,
+    GTK_SIDE_BOTTOM,
+    GTK_SIDE_LEFT,
+    GTK_SIDE_RIGHT
+} GtkSide;
+
+typedef enum {
+    GTK_ANCHOR_CENTER,
+    GTK_ANCHOR_N,
+    GTK_ANCHOR_NW,
+    GTK_ANCHOR_NE,
+    GTK_ANCHOR_S,
+    GTK_ANCHOR_SW,
+    GTK_ANCHOR_SE,
+    GTK_ANCHOR_W,
+    GTK_ANCHOR_E
+} GtkAnchor;
+
+struct _GtkPackerChild {
+    GtkWidget *widget;
+
+    GtkAnchor anchor;
+    GtkSide side;
+    GtkPackerOptions options;
+
+    gint use_default;
+
+    gint border_width;
+    gint padX;
+    gint padY;
+    gint iPadX;
+    gint iPadY;
+};
+
+struct _GtkPacker {
+    GtkContainer parent;
+
+    GList *children;
+
+    gint spacing;
+
+    gint default_border_width;
+    gint default_padX;
+    gint default_padY;
+    gint default_iPadX;
+    gint default_iPadY;
+};
+
+struct _GtkPackerClass {
+    GtkContainerClass parent_class;
+};
+
+
+GtkType    gtk_packer_get_type     (void);
+GtkWidget* gtk_packer_new          (void);
+void       gtk_packer_add_defaults (GtkPacker        *packer, 
+                                    GtkWidget        *child,
+                                    GtkSide          side,
+                                    GtkAnchor        anchor,
+                                    GtkPackerOptions options);
+void       gtk_packer_add          (GtkPacker        *packer, 
+                                    GtkWidget        *child,
+                                    GtkSide          side,
+                                    GtkAnchor        anchor,
+                                    GtkPackerOptions options,
+                                    gint border_width, 
+                                    gint padX, 
+                                    gint padY,
+                                    gint ipadX,
+                                    gint ipadY);
+void       gtk_packer_configure    (GtkPacker        *packer, 
+                                    GtkWidget        *child,
+                                    GtkSide          side,
+                                    GtkAnchor        anchor,
+                                    GtkPackerOptions options,
+                                    gint border_width, 
+                                    gint padX, 
+                                    gint padY,
+                                    gint ipadX,
+                                    gint ipadY);
+void       gtk_packer_set_spacing (GtkPacker *packer, gint spacing);
+void       gtk_packer_set_default_border_width(GtkPacker *packer, gint border);
+void       gtk_packer_set_default_pad(GtkPacker *packer, gint padX ,gint padY);
+void       gtk_packer_set_default_ipad(GtkPacker *packer, gint iPadX ,gint iPadY);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_PACKER_H__ */